#include "sitetest.h"

/*Registry this TestSuite to theTestFactoryRegistry*/
CPPUNIT_TEST_SUITE_REGISTRATION (SiteTest);

void SiteTest::setUp() {
	SG_init();
	s1=NULL;
	s2=NULL;
	s1 = new Site("site1", 100);
	s2 = new Site("site2", "../data/traces/cputrace.1", 0, "../data/traces/cputrace.1");	
}

void SiteTest::testConstructorException() { fprintf(stderr,">>> SiteTest::testConstructorException()\n");
	Site *s=NULL;
	try {
		s = new Site("Fake", "NOT_FOUND", 0, "NOT_FOUND");		
		CPPUNIT_FAIL("An exception should be throwed!!");
	} catch (std::runtime_error &e) {
		//Pass
	}
}

void SiteTest::testGetDomainAndLink() { fprintf(stderr,">>> SiteTest::testGetDomainAndLink()\n");
	//Test Domain
	CPPUNIT_ASSERT(!strcmp(s1->getDomain(),"site1"));
	CPPUNIT_ASSERT(!strcmp(s2->getDomain(),"site2"));
	
	//Test Link
	CPPUNIT_ASSERT(!strcmp(s1->getLink()->getName(),"intralink_site1"));
	CPPUNIT_ASSERT(!strcmp(s2->getLink()->getName(),"intralink_site2"));

	CPPUNIT_ASSERT(s1->getLink()->getBandwidth(0)==s1->getLink()->getBandwidthLimit(0));

//FALTA VER PROBLEMA DO OFFSET INCIAL NO CODIGO DO SIMGRID PARA BW_LIM
//	printf("s2-bw[0]=%Lf  bwlim[0]=%Lf\n",s2->getLink()->getBandwidth(0),s2->getLink()->getBandwidthLimit(0));
//	printf("s2-bw[110]=%Lf  bwlim[110]=%Lf\n",s2->getLink()->getBandwidth(110),s2->getLink()->getBandwidthLimit(110));	
	CPPUNIT_ASSERT(s2->getLink()->getBandwidth(0)==s2->getLink()->getBandwidthLimit(0));
	CPPUNIT_ASSERT(s2->getLink()->getBandwidth(110)==s2->getLink()->getBandwidthLimit(110));		

	//Test Storage
	CPPUNIT_ASSERT(!strcmp(s1->getStorage()->getName(),"storage_site1"));
	CPPUNIT_ASSERT(!strcmp(s2->getStorage()->getName(),"storage_site2"));

	CPPUNIT_ASSERT(s1->getStorage()->getNumberOfDatas()==0);				
	CPPUNIT_ASSERT(s2->getStorage()->getNumberOfDatas()==0);				

}

void SiteTest::testAddProcessor() { fprintf(stderr,">>> SiteTest::testAddProcessor()\n");
	//CPU available Fixed
	s1->addProcessor(1, 1);
	s1->addProcessor(2,0.9);
	CPPUNIT_ASSERT(s1->getNumberOfProcessors()==2);
	CPPUNIT_ASSERT(!strcmp("processor_1_site1",s1->getProcessorByIndex(0)->getName()));
	CPPUNIT_ASSERT(!strcmp("processor_2_site1",s1->getProcessorByIndex(1)->getName()));	

	//CPU available trace-based
	s2->addProcessor(1,"../data/traces/cputrace.0", 0, "../data/traces/cpuerror.0", "../data/traces/cputrace.0");
	s2->addProcessor(2,"../data/traces/cputrace.0", 0, "../data/traces/cpuerror.0","../data/traces/cputrace.0");
	CPPUNIT_ASSERT(s2->getNumberOfProcessors()==2);
	CPPUNIT_ASSERT(!strcmp("processor_1_site2",s2->getProcessorByIndex(0)->getName()));
	CPPUNIT_ASSERT(!strcmp("processor_2_site2",s2->getProcessorByIndex(1)->getName()));	

	//Processor not found test	
	try {
	s2->addProcessor(1,"NOT_FOUND", 0, "NOT_FOUND");
	CPPUNIT_FAIL("An exception should be throwed!!");
	} catch (std::runtime_error &e) {
		//number of processors should continue to be 2
		CPPUNIT_ASSERT(s2->getNumberOfProcessors()==2);
	}
}

void SiteTest::testGetProcessorByName() { fprintf(stderr,">>> SiteTest::testGetProcessorByName()\n");
	s2->addProcessor(1,"../data/traces/cputrace.0", 0, "../data/traces/cpuerror.0", "../data/traces/cputrace.0");	
	try {
		s2->getProcessorByName("PROCESSOR");	
		CPPUNIT_FAIL("An exception should be throwed!!");
	} catch (std::runtime_error &e) {
		//Pass
	}

	Processor *p = s2->getProcessorByName("processor_1_site2");	
	CPPUNIT_ASSERT(p->getCpuSpeed()==1);
}

void SiteTest::testHasData() { fprintf(stderr,">>> SiteTest::testHasData()\n");
	s2->getStorage()->addData("input_task_1",100, DataElement::INPUT_DATA);

	DataElement *d1 = new DataElement("input_task_1", 100, DataElement::INPUT_DATA);
	DataElement *d2 = new DataElement("input_task_2", 200, DataElement::INPUT_DATA);	

	CPPUNIT_ASSERT(s2->hasData(d1)==true);
	CPPUNIT_ASSERT(s2->hasData(d2)==false);	
}

void SiteTest:: testSiteIsBusy() { fprintf(stderr,">>> SiteTest::testSiteIsBusy()\n");
	//No processors at site
	CPPUNIT_ASSERT(s1->allProcessorsAreBusy()==true);		
	
	s1->addProcessor(1, 1);
	s1->addProcessor(2,0.9);
	s1->addProcessor(2,0.9);	
	s1->addProcessor(1, 1);	

	SG_Task fakeTask = SG_newTask (SG_COMPUTATION, "task1", 100, NULL);
	SG_Task fakeTask2 = SG_newTask (SG_COMPUTATION, "task2", 100, NULL);
	SG_Task fakeTask3 = SG_newTask (SG_COMPUTATION, "task3", 100, NULL);
	SG_Task fakeTask4 = SG_newTask (SG_COMPUTATION, "task4", 100, NULL);
	
	SG_scheduleTaskOnResource(fakeTask, s1->getProcessorByIndex(0)->getSGResource());
	SG_scheduleTaskOnResource(fakeTask2, s1->getProcessorByIndex(1)->getSGResource());
	SG_scheduleTaskOnResource(fakeTask3, s1->getProcessorByIndex(2)->getSGResource());	
	
	CPPUNIT_ASSERT(s1->getProcessorByIndex(0)->isBusy()==true);
	CPPUNIT_ASSERT(s1->getProcessorByIndex(1)->isBusy()==true);
	CPPUNIT_ASSERT(s1->getProcessorByIndex(2)->isBusy()==true);
	CPPUNIT_ASSERT(s1->getProcessorByIndex(3)->isBusy()==false);			
	
	CPPUNIT_ASSERT(s1->allProcessorsAreBusy()==false);	
	
	SG_scheduleTaskOnResource(fakeTask4, s1->getProcessorByIndex(3)->getSGResource());		

	CPPUNIT_ASSERT(s1->getProcessorByIndex(3)->isBusy()==true);			
	
	CPPUNIT_ASSERT(s1->allProcessorsAreBusy()==true);		
}

void SiteTest::tearDown() {
	if (s1) delete s1;
	if (s2) delete s2;
	SG_clear();
}



